/**********************************************************************
  SPGLib - SPGLibTest class provides unit testing for SPGLib

  Copyright (C) 2010 David C. Lonie

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 **********************************************************************/

#include <globalsearch/formats/poscarformat.h>

#include <xtalopt/structures/xtal.h>

#include <sstream>

#include <QDebug>
#include <QString>
#include <QtTest>

#define FROMPIO_TOL 0.05

using namespace XtalOpt;

class SPGLibTest : public QObject
{
  Q_OBJECT

private:
  Xtal* m_xtal;

private slots:
  /**
   * Called before the first test function is executed.
   */
  void initTestCase();

  /**
   * Called after the last test function is executed.
   */
  void cleanupTestCase();

  /**
   * Called before each test function is executed.
   */
  void init();

  /**
   * Called after every test function.
   */
  void cleanup();

  // Tests
  //  Simple test to make sure that nothing is seriously broken
  void idealBCC();

  //  Tests that have shown problems
  void fromPio1();
  void fromPio2();
  void fromPio3();
  void fromPio4();
  void fromPio5();
  void fromPio6();
  void fromPio7();
  void fromPio8();
};

void SPGLibTest::initTestCase()
{
}

void SPGLibTest::cleanupTestCase()
{
}

void SPGLibTest::init()
{
  m_xtal = new Xtal;
}

void SPGLibTest::cleanup()
{
  if (m_xtal) {
    delete m_xtal;
    m_xtal = 0;
  }
}

void SPGLibTest::idealBCC()
{
  m_xtal->setCellInfo(3.0, 3.0, 3.0, 90.0, 90.0, 90.0);

  // Build bcc structure
  GlobalSearch::Atom& atm1 = m_xtal->addAtom();

  atm1.setPos(Eigen::Vector3d(0.0, 0.0, 0.0));
  atm1.setAtomicNumber(1);

  GlobalSearch::Atom& atm2 = m_xtal->addAtom();
  atm2.setPos(Eigen::Vector3d(1.5, 1.5, 1.5));
  atm2.setAtomicNumber(1);

  m_xtal->findSpaceGroup();
  QCOMPARE(m_xtal->getSpaceGroupNumber(), 229U);
  QCOMPARE(m_xtal->getSpaceGroupSymbol(), QString("Im-3m"));
  QCOMPARE(
    m_xtal->getHTMLSpaceGroupSymbol(),
    QString(
      "<HTML>Im<span style=\"text-decoration: overline\">3</span>m</HTML>"));
}

void SPGLibTest::fromPio1()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio 1\n\
   1.00000000000000\n\
     6.0566497821097043    0.3795121972298890    0.0416889858265167\n\
     1.1892305190531443    2.6030960258193159   -0.0094870012677909\n\
    -0.5988630056472680   -1.2540077098048823    2.5018934392124548\n\
  H    He\n\
  18   2\n\
Direct\n\
  0.3595174582943753  0.5176827568981921  0.0012114976337420\n\
  0.7225791892967559  0.5076971291774203  0.6481950697065459\n\
  0.0698939458762775  0.4157742719950184  0.9274907124380144\n\
  0.0697627563137735  0.8795223041070420  0.3935062668041655\n\
  0.0599618376458357  0.3219093523037698  0.4920593659107028\n\
  0.5700474147042542  0.5958569156889288  0.2483146452411631\n\
  0.7564008059540728  0.8185841738045437  0.3032567839611864\n\
  0.5858014370160861  0.2444031336587713  0.5946505820807004\n\
  0.2566102910903806  0.2843150504257914  0.3371762409353116\n\
  0.5858335854443069  0.6974200671154371  0.0481837256445709\n\
  0.3901262038197285  0.1688711406511725  0.3189859356241224\n\
  0.2225770912212840  0.6632539334212298  0.9928511728845461\n\
  0.8899389874294216  0.6670256283206281  0.3214713883251348\n\
  0.8594749399598607  0.3792242142205383  0.6392373425020790\n\
  0.0856848206680562  0.2009593974856005  0.0460867402881626\n\
  0.5697801939326591  0.0610201932622665  0.7130201663515697\n\
  0.0861797032443645  0.7453681950826812  0.5932837305405847\n\
  0.5600355158774711  0.1714650538951173  0.1461758468824457\n\
  0.3424316793489581  0.8742328696958156  0.6616426675432113\n\
  0.8425094428620844  0.0566577187900324  0.9787883487020472\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  xtal.findSpaceGroup(FROMPIO_TOL);
  // "spglib finds Ima2 (#46) whereas findsym detects Cmc2_1" with
  // tol=0.05
  QEXPECT_FAIL("", "spglib: P1, findsym: Cmc2_1", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("Cmc2_1"));
}

void SPGLibTest::fromPio2()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio 2\n\
   1.00000000000000\n\
     3.7668658779046242   -0.2526363169248627   -0.3909143489813395\n\
     0.4126424943540823    7.5129095763967930   -0.0136225756754529\n\
     0.6901112196345119    0.0603991507863854    7.4962532790130991\n\
   H   He Li\n\
   4   4  12\n\
Direct\n\
  0.9525215854179879  0.1735141612887874  0.7435424941602350\n\
  0.9524739822599507  0.6735210653178597  0.2434632277491809\n\
  0.9524597533682075  0.6768418642821685  0.7401677083403142\n\
  0.9525357970439058  0.1768643727314607  0.2402074707235176\n\
  0.5042814350986156  0.4060570640528923  0.9634950823257925\n\
  0.5043776071753769  0.3971423498507791  0.4725044636138762\n\
  0.5043541530369365  0.9061088755369511  0.4633792004988111\n\
  0.5040377679741697  0.8970685669303987  0.9723981712277499\n\
  0.4395713802410722  0.1877909978827128  0.7553060494815979\n\
  0.9158719130536632  0.9307118467682090  0.2376235115863232\n\
  0.4395653037379523  0.1883698213177756  0.2548042015674308\n\
  0.4395074161919428  0.6883731372626732  0.7547580735678250\n\
  0.9287250570758719  0.4298180259292276  0.2716754705129796\n\
  0.9286085523637826  0.2048168416405981  0.9966170013660888\n\
  0.9158232419533636  0.6707213209807763  0.9974502608217271\n\
  0.9283827894076810  0.7047056862464066  0.4965602196967903\n\
  0.9287713911515645  0.9298090277507504  0.7716838694177337\n\
  0.9158562604089533  0.4306908021571946  0.7375890681822121\n\
  0.4395130866383787  0.6878349360194402  0.2551439498569619\n\
  0.9157795264006211  0.1707042360529422  0.4975145053028533\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  xtal.findSpaceGroup(FROMPIO_TOL);
  QEXPECT_FAIL("", "spglib: P1, findsym: Pc", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("Pc"));
}

void SPGLibTest::fromPio3()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio\n\
   1.00000000000000\n\
     3.7484850618560537    0.5179527621527573    0.2725676000178477\n\
     2.5954120365612385    7.9478524331504028    0.7065992265067038\n\
     3.1731369922769055    0.0785542643845797    7.7623356251774149\n\
   H   He Li\n\
   4   4  12\n\
Direct\n\
  0.4389346288864205  0.1795598238971019  0.7431541681120870\n\
  0.4389412564990736  0.6795644110895200  0.2431557484978026\n\
  0.9389356389821629  0.6765346698939011  0.7461778169618284\n\
  0.9389501232170477  0.1765415445420275  0.2461756297366314\n\
  0.3390501567323055  0.4481451150190989  0.0224142991053908\n\
  0.8390147964137699  0.4563780753333657  0.5142060952865755\n\
  0.3390152622678815  0.9481162864188853  0.5224106714099574\n\
  0.8390355287372468  0.9564111778151828  0.0142011459673810\n\
  0.9781846373640883  0.1649408017525918  0.7314431658862622\n\
  0.2466718723094136  0.9231612147636865  0.2162428250409335\n\
  0.4780695044177173  0.1643555753931630  0.2321488003074096\n\
  0.4780507965806047  0.6643414392518678  0.7321621645020625\n\
  0.7276808634381611  0.4223653701660671  0.2479653568307503\n\
  0.2276784133946161  0.1810091104319382  0.9891980490356383\n\
  0.7463791888996706  0.6492677818631516  0.9900013558969673\n\
  0.2276808569331891  0.6810235977688703  0.4892004444024919\n\
  0.7276847343627200  0.9223598206645673  0.7479570915952536\n\
  0.2466458869191910  0.4231569924803437  0.7162315854213671\n\
  0.9781965053169768  0.6649451293532957  0.2314368458367852\n\
  0.7463983483277447  0.1492850621013686  0.4899991401664211\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  xtal.findSpaceGroup(FROMPIO_TOL);
  QEXPECT_FAIL("", "spglib: P1, findsym: Pc", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("Pc"));
}

void SPGLibTest::fromPio4()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio\n\
   1.00000000000000\n\
     3.0399837305035393   -0.2689430591255473    0.3854696358687387\n\
     2.3242680883263844    8.9135745201241541    0.1859370039210433\n\
     0.5019497901415106    1.1955705707455986    9.1769697990207320\n\
   H   He Li\n\
   4   4  12\n\
Direct\n\
  0.6365543883399805  0.2168683250241590  0.8349212688156322\n\
  0.3180000041714035  0.9560280191806216  0.7340163351485731\n\
  0.8777658498052986  0.1151121088405078  0.4550310878776788\n\
  0.1065864621846289  0.0072121351676283  0.1059871883491276\n\
  0.8956928686074498  0.3695383567748922  0.1624958578471075\n\
  0.1922885604268676  0.4192789041684393  0.5205495216332791\n\
  0.9488203816782870  0.5994115216774315  0.8292348064600047\n\
  0.5898435066848926  0.7942902854820374  0.3520358955206325\n\
  0.3599410765687004  0.2377653830839307  0.3669711624331613\n\
  0.7524476676322344  0.0257219682341220  0.7953979917597759\n\
  0.5759129909960143  0.1345892233591163  0.0382336680660868\n\
  0.3676355339298624  0.7757062443086886  0.8147813248507079\n\
  0.3917193637416118  0.5021606191740612  0.0381871115153924\n\
  0.5565967621554688  0.5620020817252123  0.6498210853653984\n\
  0.3938088061491354  0.9971691044555090  0.5413402125396135\n\
  0.0109879077720433  0.0004392493049988  0.3040222591491542\n\
  0.0915177347389307  0.3099506674339617  0.8313742862297122\n\
  0.7396062065249935  0.2436662766992443  0.6014294689601524\n\
  0.6674747362028992  0.8704642893766082  0.1224072925140652\n\
  0.7367029916892964  0.5218437165288294  0.3287928749647472\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  xtal.findSpaceGroup(FROMPIO_TOL);
  QEXPECT_FAIL("", "spglib: P1, findsym: Cm", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("Cm"));
}

void SPGLibTest::fromPio5()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio\n\
   1.00000000000000\n\
     3.0862034428882930   -0.0061740449954627    0.0771065378323145\n\
    -0.0055817307757720    8.9378071882876462    1.0714808471957371\n\
    -1.7595384299272794   -1.6712253860455217    8.5174514397732199\n\
   H   He Li\n\
   4   4  12\n\
Direct\n\
  0.7547618719861585  0.3709352584036946  0.8230239017554005\n\
  0.6443508030928182  0.5454740910209043  0.5381432194472726\n\
  0.1062598885949522  0.2749413120284499  0.5336098522688195\n\
  0.2905875486578091  0.1004206121165623  0.8185004046861083\n\
  0.9297688542593573  0.1201878185036251  0.1619513616718719\n\
  0.9384630226831360  0.5261913092938726  0.1947748632807444\n\
  0.5712063114181114  0.9157174396752665  0.4936963142826873\n\
  0.2526914069082718  0.7301215757162289  0.8629747740075776\n\
  0.5885785991643846  0.2059496924559126  0.6821007421686507\n\
  0.7830989072993487  0.5533003058122447  0.9262417846511573\n\
  0.0822153391481205  0.4403736916886365  0.6739116006240883\n\
  0.5463548945355902  0.3550867628012769  0.4390531475907071\n\
  0.6649389611065935  0.7006297095938352  0.6814275044074063\n\
  0.1645368528607244  0.9454748234433605  0.6751850183046780\n\
  0.8271559009576183  0.0355078280357572  0.9145445869245249\n\
  0.0848109682071294  0.6108859194665607  0.4420059034073893\n\
  0.4382664209869460  0.9691193700624927  0.1822645552220600\n\
  0.0368252033973344  0.0925606680223063  0.4302065522766315\n\
  0.4262835864572549  0.6772099041761191  0.1738038318846121\n\
  0.2896425582783375  0.2910093076828788  0.9171800811376110\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  xtal.findSpaceGroup(FROMPIO_TOL);
  QEXPECT_FAIL("", "spglib: P1, findsym: C2", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("C2"));
}

void SPGLibTest::fromPio6()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio\n\
   1.00000000000000\n\
     4.7942520956467618    1.8132449716985586    1.4056177222130293\n\
     0.9704420851364433    5.2472757220847637   -0.0319252043134948\n\
    -0.7125145139300034   -5.2812187925442569    9.2463501243322401\n\
   H   He Li\n\
   4   4  12\n\
Direct\n\
  0.6132393258962139  0.5093212166281099  0.2491032478593813\n\
  0.1132361501382182  0.5093253872552627  0.4991004961922642\n\
  0.1132341501382161  0.5093273872552576  0.9991024961922591\n\
  0.6132403258962114  0.5093212166281099  0.7491022478593767\n\
  0.8835744293252432  0.9687073199303989  0.3841365540657756\n\
  0.3835205431545627  0.9687223525994858  0.1341457509046580\n\
  0.8835734293252457  0.9687103199303985  0.8841385540657777\n\
  0.3835215431545673  0.9687213525994883  0.6341437509046559\n\
  0.3128398967974319  0.0189254279547384  0.8640621686521445\n\
  0.4039701697167126  0.4888677712238338  0.5989619684257496\n\
  0.3128398967974319  0.0189276279547357  0.3640641686521466\n\
  0.8128037616748905  0.5798935619454914  0.3945428636351558\n\
  0.8429745940861260  0.5800730975794738  0.1445751729598932\n\
  0.3429416892717691  0.4888120730264633  0.3489346460144048\n\
  0.9040044399388294  0.0189382918567536  0.6140081312905754\n\
  0.3429416892717691  0.4888120730264633  0.8489336460144074\n\
  0.4039661697167156  0.4888687712238313  0.0989622684257531\n\
  0.8429755940861234  0.5800750975794758  0.6445761729598907\n\
  0.8128017616748885  0.5798945619454959  0.8945428636351559\n\
  0.9040034399388319  0.0189356918567516  0.1140071312905779\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  xtal.findSpaceGroup(FROMPIO_TOL);
  QEXPECT_FAIL("", "spglib: P1, findsym: R3c", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("R3c"));
}

void SPGLibTest::fromPio7()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio\n\
   1.00000000000000\n\
     5.2386732990927829    0.0620684076961739   -0.8967987333915093\n\
     2.3679063142316981    4.4775818945618298   -1.6088112683742066\n\
     1.7347298504277189   -3.6803835541052039    9.8687247185511779\n\
   H   He Li\n\
   4   4  12\n\
Direct\n\
  0.0962798210161998  0.5170843566615981  0.2630526154233745\n\
  0.5962754807006138  0.5169623503816645  0.5130279899581097\n\
  0.5963155510814035  0.5168358038460884  0.0129959699724357\n\
  0.0962735166431018  0.5168407092014133  0.7629937318816394\n\
  0.8261107796303290  0.0574718682112428  0.6684702093732453\n\
  0.3261951799956889  0.0572013971333357  0.9184814857397195\n\
  0.8261272244649722  0.0576268664705952  0.1684664169604693\n\
  0.3261949383395789  0.0574370121569265  0.4184863275298087\n\
  0.3964235407574523  0.0073884068532714  0.6229646864128351\n\
  0.8963380376244441  0.4465043666947668  0.3729738986883339\n\
  0.3965315636519186  0.0073811592615584  0.1230233097908227\n\
  0.3056171906240864  0.5375565794150340  0.6232002983091213\n\
  0.3662707565706725  0.5375237171031766  0.3731765041163740\n\
  0.8664413937918374  0.4465521566853209  0.1231132123325286\n\
  0.8054735826178311  0.0073840257945862  0.8731461553303717\n\
  0.8664350177463623  0.4466318334241460  0.6230750692665478\n\
  0.8963222349590436  0.4463498121000720  0.8730004106198560\n\
  0.3662973036906439  0.5373795046009668  0.8731841025308469\n\
  0.3055698460566810  0.5376042224815617  0.1232255686839733\n\
  0.8055230400371350  0.0074671815226643  0.3731271370795857\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  QEXPECT_FAIL("", "spglib: P1, findsym: R3c", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("R3c"));
}

void SPGLibTest::fromPio8()
{
  // This is part of a collection of POSCARs that Pio Baettig found
  // that gave different results in FINDSYM from what spglib reported.

  std::stringstream poscar("\
FromPio\n\
   1.00000000000000\n\
     5.2386732990927829    0.0620684076961739   -0.8967987333915093\n\
     2.3679063142316981    4.4775818945618298   -1.6088112683742066\n\
     1.7347298504277189   -3.6803835541052039    9.8687247185511779\n\
   H   He Li\n\
   4   4  12\n\
Direct\n\
  0.0962798210161998  0.5170843566615981  0.2630526154233745\n\
  0.5962754807006138  0.5169623503816645  0.5130279899581097\n\
  0.5963155510814035  0.5168358038460884  0.0129959699724357\n\
  0.0962735166431018  0.5168407092014133  0.7629937318816394\n\
  0.8261107796303290  0.0574718682112428  0.6684702093732453\n\
  0.3261951799956889  0.0572013971333357  0.9184814857397195\n\
  0.8261272244649722  0.0576268664705952  0.1684664169604693\n\
  0.3261949383395789  0.0574370121569265  0.4184863275298087\n\
  0.3964235407574523  0.0073884068532714  0.6229646864128351\n\
  0.8963380376244441  0.4465043666947668  0.3729738986883339\n\
  0.3965315636519186  0.0073811592615584  0.1230233097908227\n\
  0.3056171906240864  0.5375565794150340  0.6232002983091213\n\
  0.3662707565706725  0.5375237171031766  0.3731765041163740\n\
  0.8664413937918374  0.4465521566853209  0.1231132123325286\n\
  0.8054735826178311  0.0073840257945862  0.8731461553303717\n\
  0.8664350177463623  0.4466318334241460  0.6230750692665478\n\
  0.8963222349590436  0.4463498121000720  0.8730004106198560\n\
  0.3662973036906439  0.5373795046009668  0.8731841025308469\n\
  0.3055698460566810  0.5376042224815617  0.1232255686839733\n\
  0.8055230400371350  0.0074671815226643  0.3731271370795857\n");

  Xtal xtal;
  QVERIFY(GlobalSearch::PoscarFormat::read(xtal, poscar));
  QEXPECT_FAIL("", "spglib: P1, findsym: Pm", Continue);
  QCOMPARE(xtal.getSpaceGroupSymbol(), QString("Pm"));
}

QTEST_MAIN(SPGLibTest)

#include "spglibtest.moc"
